import java.awt.Color;
import java.awt.Point;
import java.util.ArrayList;

import pulpcore.animation.Easing;
import pulpcore.animation.Int;
import pulpcore.animation.event.RemoveSpriteEvent;
import pulpcore.image.BlendMode;
import pulpcore.image.Colors;
import pulpcore.image.CoreGraphics;
import pulpcore.image.CoreImage;
import pulpcore.image.filter.*;
import pulpcore.Input;
import pulpcore.scene.Scene2D;
import pulpcore.sprite.FilledSprite;
import pulpcore.sprite.Group;
import pulpcore.sprite.ImageSprite;
import pulpcore.sprite.Sprite;
import pulpcore.Stage;
import static pulpcore.image.Colors.*;

public class Test2 extends Scene2D {
    
    String[] tiles = {
        "Water Block.png",
        "Stone Block.png",
        "Grass Block.png",
        "Dirt Block.png",
    };
    
    String[] map = {
        "GGGGGGGGGGGGGGGGGGGGGG",
        "GGGGGGGGGGWWWWWWWWWGGG",
        "GGGDSSDGGGWWWWWWWWWGGG",
        "GGGDSSDGGGWWWWWWWWWGGG",
        "GGGDSSDGGGWWWWWWWWWGGG",
        "GGGGGGGGGGWWWWWWWWWGGG",
        "GGGGGGGGGGGGGGGGGGGGGG",
        "GGGGGGGGGGDDDDDDDDGGGG",
        "GGGGGGGGGGGGGGSSGGGGGG",
        "GGGGGGGGGGGGGGSSGGGGGG",
        "GGGGGGGSSSSSSSSSGGGGGG",
        "GGGGGGGSSSSSSSSSGGGGGG",
    };
    String[] map2 = {
         "W"
        };
    ImageSprite[][] grid = new ImageSprite[map[0].length()][map.length];
    Tile[][] tilegrid = new Tile[map[0].length()][map.length];
    TileMapSprite tileMap;
    ImageSprite cursor;
    Group mapSprites;

    Character selectedchar;
    
   
    //Character selected = new Character;
    ImageSprite nicky = new ImageSprite("warrior1.png", Stage.getWidth()/2, 0);
    ImageSprite evan = new ImageSprite("tank1.png", Stage.getWidth()/2, 100);
    ImageSprite joel = new ImageSprite("berserker1.png", Stage.getWidth()/2, 100);
    ImageSprite zenwa = new ImageSprite("warrior.png", Stage.getWidth()/2, 100);
   // ImageSprite player4 = new ImageSprite("warrior.png", Stage.getWidth()/2, 100);
    //Character selected = new Character;

//<<<<<<< .mine
    Point j = new Point(3,6);
    Point e = new Point(3,5);
    Role warrior = new Role("badass", "sword");
    Role tank = new Role("tank", "lance");
    Role berserker = new Role ("berserker", "axe");
   
//=======
    Character Joel = new Character("Joel", joel, berserker, new Point(0,0) ,10, 30, 18, 5, 5, 10, 20, 9, 12);
    Character Evan = new Character("Evan", evan, tank, new Point(2,3) , 10, 30, 15, 10, 3, 1, 1, 1, 1);
    Character Nicky = new Character("Nicky", nicky, warrior, new Point(6,6) , 10, 30, 20, 10, 10, 10, 11, 2, 7);
    Character Zenwa = new Character("Zenwa", zenwa, warrior, new Point(6,5) , 100, 100, 100, 100, 100, 100, 100, 100, 100);
   // Character Tank = new Character("Tank", player4, tank, new Point(3,4), 10, 35, 15, 10, 4, 3, 0, 5, 3);


    PlayerTeam team = new PlayerTeam();
    EnemyTeam team2 = new EnemyTeam();
//>>>>>>> .r21
    @Override
    public void load() {
        // Add the background (sky-blue)
        add(new FilledSprite(rgb(100, 200, 255)));
        
        
        team.add(Joel);
        team.add(Evan);
        Nicky.getSprite().setFilter(new Glow(.1));
      //  Tank.getSprite().setFilter(new Glow(.3));
        team2.add(Nicky);
        //team2.add(Zenwa);
        
        // Add the tileset
        tileMap = createTileMapSprite(tiles, map2, 100, 80);
        
        add(tileMap);
        
        mapSprites = new Group();
        
        for (int i = 0; i < map.length; i++){
        	for (int j = 0; j < map[0].length(); j++)
        	{
        		if (map[i].charAt(j) == 'G')
        			grid[j][i] = new ImageSprite("Grass Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'S')
            		grid[j][i] = new ImageSprite("Stone Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'W')
            		grid[j][i] = new ImageSprite("Water Block.png",j*100,i*80);
        		if (map[i].charAt(j) == 'D')
            		grid[j][i] = new ImageSprite("Dirt Block.png",j*100,i*80);
        		mapSprites.add(grid[j][i]);
        		tilegrid[j][i] = new Tile(new Point(j,i), grid[j][i]);
        	}
        }        
        

        mapSprites.add(joel);
        mapSprites.add(evan);
        mapSprites.add(nicky);
        //mapSprites.add(zenwa);
        
      
        
        grid[1][1].setFilter(new Glow(.1));
        
        for (Character i : team.getTeam())
        {
        	i.getSprite().moveTo(i.getPositionX()*100,i.getPositionY()*80-80, 100);
        	tilegrid[i.getPositionX()][i.getPositionY()].setCharacter(i);
        }
        for (Character i : team2.getTeam())
        {
        	i.getSprite().moveTo(i.getPositionX()*100,i.getPositionY()*80-80, 100);
        	tilegrid[i.getPositionX()][i.getPositionY()].setCharacter(i);

        }
        
        
        // Add the cursor

        
        mapSprites.x.bindTo(tileMap.viewX);
        mapSprites.y.bindTo(tileMap.viewY);
        add(mapSprites);
        
        setCursor(Input.CURSOR_OFF);
        cursor = new ImageSprite("cursor.png", 0, 0);
        cursor.setBlendMode(BlendMode.Add());
        cursor.bindLocationTo(tileMap);
        add(cursor);
        
    }
    
    @Override
    public void update(int elapsedTime) {
        	
            cursor.setLocation(Input.getMouseX(), Input.getMouseY());
            if (selectedchar != null){
            	for (int i = selectedchar.getPositionY()-selectedchar.getMove()-selectedchar.getRange(); i <= selectedchar.getPositionY()+selectedchar.getMove()+selectedchar.getRange(); i++){
    	        	for (int j = selectedchar.getPositionX()-selectedchar.getMove()-selectedchar.getRange(); j <= selectedchar.getPositionX()+selectedchar.getMove()+selectedchar.getRange(); j++)
    	        	{
    	        		if (i > -1 && i < map.length && j > -1 && j < map[0].length())
    	        		{
    	        			if (Math.abs(selectedchar.getPositionY()-i)+Math.abs(selectedchar.getPositionX()-j) < selectedchar.getMove()+selectedchar.getRange())
            				{	     
    	        				tilegrid[j][i].setSuperSpecial();
    	        				if (tilegrid[j][i].getCharacter() != null)
    	        				{
    	        					if (!selectedchar.canAttack(tilegrid[j][i].getCharacter()))
    	        					{
    	        						tilegrid[j][i].unSuperSpecial();
    	        					}
    	        				}
            					
            				}
    	        		}
    	        	}
    	        }
    	        for (int i = selectedchar.getPositionY()-selectedchar.getMove(); i <= selectedchar.getPositionY()+selectedchar.getMove(); i++){
    	        	for (int j = selectedchar.getPositionX()-selectedchar.getMove(); j <= selectedchar.getPositionX()+selectedchar.getMove(); j++)
    	        	{
    	        		if (i > -1 && i < map.length && j > -1 && j < map[0].length())
    	        		{
    	        			if (Math.abs(selectedchar.getPositionY()-i)+Math.abs(selectedchar.getPositionX()-j) < selectedchar.getMove())
            				{	     
            					if (tilegrid[j][i].getCharacter() == null)
            					{
            						tilegrid[j][i].setSpecial();
            					}
            					
            				}
    	        		}
    	        	}
    	        }
    	        
            }
            else
            {
                for (int i = 0; i < map.length; i++){
                	for (int j = 0; j < map[0].length(); j++)
                	{
    	        		tilegrid[j][i].unSpecial();
    	        		tilegrid[j][i].unSuperSpecial();
    	        	}
            	}
            }
        if (Input.isMousePressed())
        {
            int x = Input.getMousePressX();
            int y = Input.getMousePressY();
            int goalX = tileMap.viewX.get() - (x - Stage.getWidth() /2)/2;
            int goalY = tileMap.viewY.get() - (y - Stage.getHeight() /2)/2;
                        //move character
            
            if(selectedchar != null && team2.isClicked(selectedchar, tilegrid) != null){
            	Character enemy = team2.isClicked(selectedchar, tilegrid);
            	if(selectedchar.canAttack(enemy)){
            		selectedchar.attackPlan(enemy);
            		if (Math.abs(selectedchar.getPositionX() - enemy.getPositionX())+Math.abs(selectedchar.getPositionY() - enemy.getPositionY()) <= selectedchar.getRange())
    				{
	            		if(Input.isAltDown() && tilegrid[enemy.getPositionX()][enemy.getPositionY()].getSuperSpecial()){	
	            		selectedchar.battle(enemy);
			            selectedchar.justActed(true);
			            selectedchar = null;
	            		}
    				}
            	}
            }
            else if (selectedchar != null && team.isClicked(selectedchar, tilegrid) == null && !(x < 100 || x > Stage.getWidth() - 100)&& !(y < 100 || y > Stage.getHeight() - 100)&& !Input.isControlDown())
            {
                    for (int i = 0; i < map.length; i++){
                    	for (int j = 0; j < map[0].length(); j++)
                    	{
                    		if (selectedchar != null)
                            {
    		                	if (tilegrid[j][i].getSprite().isMousePressed()){
    		                		if (tilegrid[j][i].getSpecial())
    		                    	{
    		                         	tilegrid[selectedchar.getPositionX()][selectedchar.getPositionY()].setCharacter(null);
    			                		selectedchar.setPosition(j,i);
    			                		tilegrid[j][i].setCharacter(selectedchar);
    			                		selectedchar.getSprite().moveTo(j*100, i*80-80, 100);
    			                		selectedchar = null;
    		                    	}
    			                }
                            }
                    	}
                    }
               
                
            } 
           else if(x < 100 || x > Stage.getWidth() - 100)
            	 tileMap.viewX.animateTo(goalX, 500, Easing.REGULAR_OUT);
            else if(y < 100 || y > Stage.getHeight() - 100)
            	tileMap.viewY.animateTo(goalY, 500, Easing.REGULAR_OUT);
        }
        Glow b = new Glow(.1);
        for(Character i: team.getTeam()){
        	i.getSprite().setFilter(null);
        }
        
        for(int i=0; i<team.getTeam().size(); i++){
        	Character x = team.getTeam().get(i);
        	if(x.isDead()){
        		tilegrid[x.getPositionX()][x.getPositionY()].setCharacter(null);
        		RemoveSpriteEvent die = new RemoveSpriteEvent(mapSprites, x.getSprite(), 10);
        		team.remove(x);
        		i--;
        	}
        }
        for(int i=0; i<team2.getTeam().size(); i++){
        	Character x = team2.getTeam().get(i);
        	if(x.isDead()){
        		tilegrid[x.getPositionX()][x.getPositionY()].setCharacter(null);
        		RemoveSpriteEvent die = new RemoveSpriteEvent(mapSprites, x.getSprite(), 10);
        		team2.remove(x);
        		i--;
        	}
        }


	        if (selectedchar != null)
	        {
	        	selectedchar.getSprite().setFilter(b);
	        }   
	        for (int i = 0; i < map.length; i++){
	        	for (int j = 0; j < map[0].length(); j++)
	        	{
	        		if  (tilegrid[j][i].getSpecial())
	        		{
	        			tilegrid[j][i].getSprite().setFilter(new ColorOverlay(Colors.BLUE,100));
	        		}
	        		else
	        		{
	        			tilegrid[j][i].getSprite().setFilter(null);
	        		}
	        		if (tilegrid[j][i].getSuperSpecial() && !tilegrid[j][i].getSpecial())
	        		{
	        			tilegrid[j][i].getSprite().setFilter(new ColorOverlay(Colors.RED,100));
	        		}
	        	}
	        }
        if(Input.isControlDown() && Input.isMousePressed()&& selectedchar!=null){
        	selectedchar.justActed(true);
        	selectedchar = null;
        }
        
        
       
        
        
        for (Character i : team.getTeam())
        {
        	if (i.selected(tilegrid) != null && selectedchar != null){
        		selectedchar.getSprite().setFilter(null);
        		selectedchar = i;
        	}else if(i.selected(tilegrid) != null)
        		selectedchar = i;

        }
       
        team.isTurnDone(team2);
        // When scrolling, disable dirty rectangles and hide the cursor
        setDirtyRectanglesEnabled(!tileMap.isScrolling());
        cursor.visible.set(Input.isMouseInside() && !tileMap.isScrolling());
      }
        
    
    
    TileMapSprite createTileMapSprite(String[] tiles, String[] map, int tileWidth, int tileHeight) {
        // Load tile images
        CoreImage[] tileImages = new CoreImage[tiles.length];
        for (int i = 0; i < tiles.length; i++) {
            tileImages[i] = CoreImage.load(tiles[i]);
        }
        
        // Create the tile map
        int mapWidth = map[0].length();
        int mapHeight = map.length;
        CoreImage[][] tileMapImages = new CoreImage[mapWidth][mapHeight];
        for (int i = 0; i < mapWidth; i++) {
            for (int j = 0; j < mapHeight; j++) {
                
                // Convert the map char to the first letter of the tile name
                // i.e., 'W' = "Water Block.png"
                char ch = map[j].charAt(i);
                int index = 0;
                for (int k = 0; k < tiles.length; k++) {
                    if (tiles[k].charAt(0) == ch) {
                        index = k;
                        break;
                    }
                }
                tileMapImages[i][j] = tileImages[index];
            }
        }
        return new TileMapSprite(tileMapImages, tileWidth, tileHeight);
    }
    
    /**
        A simple tile map.
        Limitation: the maximum width and height of a TileMap 
        (i.e. tileWidth*numTilesAcross and tileHeight*numTilesDown) should be less than 32768.
    */

    static class TileMapSprite extends Sprite{
        
        private CoreImage[][] tileMap;
        private int tileWidth;
        private int tileHeight;
        private int numTilesAcross;
        private int numTilesDown;
        
       
        public final Int viewX = new Int(this);
        public final Int viewY = new Int(this);
        
        public TileMapSprite(CoreImage[][] tileMap, int tileWidth, int tileHeight) {
            super(0, 0, Stage.getWidth(), Stage.getHeight());
            this.tileMap = tileMap;
            this.tileWidth = tileWidth;
            this.tileHeight = tileHeight;
            numTilesAcross = tileMap.length;
            numTilesDown = tileMap[0].length;
        }
        
        public CoreImage getCoreImage(int x, int y){
        	return tileMap[x][y];
        }
        public int getMapWidth() {
            return tileWidth * numTilesAcross;
        }
        
        public int getMapHeight() {
            return tileHeight * numTilesDown;
        }
        
        public boolean isScrolling() {
            return viewX.isAnimating() || viewY.isAnimating();
        }
        
        @Override 
        public void update(int elapsedTime) {
        	
            super.update(elapsedTime);
            viewX.update(elapsedTime);
            viewY.update(elapsedTime);
           
           
            
        }
        
        public void flip(int x, int y){
        	CoreImage evan = getCoreImage(x, y);
            evan.flip();
        }
        
        @Override
        protected void drawSprite(CoreGraphics g) {
            int y = viewY.get();
            for (int j = 0; j < numTilesDown; j++) {
                int x = viewX.get();
                for (int i = 0; i < numTilesAcross; i++) {
                    g.drawImage(tileMap[i][j], x, y);
                    x += tileWidth;
                }
                y += tileHeight;
            }
        }
    }
}